package valueObjects
{
	
	import mx.collections.ArrayCollection;
	import mx.collections.ArrayList;
	import mx.messaging.AbstractConsumer;
	
	import valueObjects.ConstantsObject;
	import valueObjects.CountryData;
	import valueObjects.NameAndNumberContainer;

	public class CountryData
	{
		
		public var countryName:String;
		public var minSalary:Number;
		public var meanSalary:Number;
		public var giniIndex:Number;
		public var population:Number;
		public var isUsedInCalculation:Boolean;
		public var isRealData:Boolean;
		private var constants:ConstantsObject=new ConstantsObject;
		
		public var SalaryDistribution:ArrayCollection;
		public function CountryData(countryName:String,giniIndex:Number,isUsedInCalculation:Boolean=true)
		{
			this.countryName=countryName;
			this.giniIndex=giniIndex;
			this.SalaryDistribution= generateSalaryArray();
			this.isUsedInCalculation=isUsedInCalculation;
			this.isRealData=false;
		}
		public function refreshSalaryArray():void
		{
			if (this.isRealData)
			{}
			else
			{
		 this.SalaryDistribution=generateSalaryArray()}
		}
		
		public function generateSalaryArray():ArrayCollection
		{	
			
			var numb:int;
			
			var returnArray:ArrayCollection=new ArrayCollection();
				
			// Assuming any group Y(k) would have a* Y(k-1) income we can get following expressions 
			var alpha:Number=(1-giniIndex)*5; //
			var Y0:Number=0.2; // Ratio of income of bottom 20 %
			var a:Number=constants.a;  // initial assumption for multiplicator a
			var tau:Number; // step for one sided dichotomy root finding 
			
			var variant1:Number;
			var variant2:Number;
			var variant3:Number;
			
			function calculatePolynome(a:Number):Number
				{
				var result:Number= 1+a+a*a+a*a*a+a*a*a*a;
				return result
				}
			
			// Here we find roots of system of nonlinear equations by iteration
			for (var iter:int = 0; iter < 50; iter++) 
			{	
				
				tau=constants.tau;
				// This is dichotomy root finding algorithm it is one sided because we are interested in roots where a>1.0,
				for (var dicount:int = 0; dicount < 50; dicount++)
				{
					
				 // Some dark magick. Original equations are Y0(1+a+a^2+a^3+a^4)=1 and alpha=y0(8+7a+5a^2+3a^3+a^4)
				 variant1=Math.abs(Y0-1/calculatePolynome(a));
				 variant2=Math.abs(Y0-1/calculatePolynome(a+tau));
					//if ( ( variant2<( (variant1+variant3 - Math.abs(variant1-variant3)) /2)))
				 	if ( variant1<variant2)
					{
					tau=tau/2;
					}
					else
					{
							a=a+tau;
					}
				}
				Y0=-(1-alpha)/(7+6*a+ 4*a*a + 2*a*a*a);
			}
			
			var salaryDistributionArray:Array=[0,0,0,0,0];
			
			for (var j:int = 0; j < 5; j++) 
			{
				// So we making array such that every item obtained by multiplication of previous by a, and this distribution has Gini index giniIndex 				
				salaryDistributionArray[j]= Y0*Math.pow(a,j);
				
			}
			var temp:ArrayCollection;
			temp= new ArrayCollection(salaryDistributionArray);
			return temp;
		}

		public function isEqual(comparedCountry:CountryData):Boolean
		{
			
		var result:Boolean;
		
		result=(this.countryName==comparedCountry.countryName)&&(this.giniIndex==comparedCountry.giniIndex)&&(this.isUsedInCalculation==comparedCountry.isUsedInCalculation);
		
		return result;	
			
			
		}
		
		public function createBigArray(mainArray:ArrayCollection):ArrayCollection
		{
			var bigArray:ArrayCollection= new ArrayCollection([{percent:"Bottom 20%"},
															   {percent:"20% low middle"},
															   {percent:"20% middle"},
															   {percent:"20% upper middle"},
															   {percent:"Top 20%"},
															   ]);
			
			for each (var member:CountryData in mainArray)
			{
				member.refreshSalaryArray();
				for (var i:int = 0; i < bigArray.length; i++) 
				{
					bigArray[i][member.countryName]=member.SalaryDistribution[i];
					//{name:member.countryName,p10:member.SalaryDistribution[0],p20:member.SalaryDistribution[1],p30:member.SalaryDistribution[2],p40:member.SalaryDistribution[3],p50:member.SalaryDistribution[4],p60:member.SalaryDistribution[5],p70:member.SalaryDistribution[6],p80:member.SalaryDistribution[7],p90:member.SalaryDistribution[8],p100:member.SalaryDistribution[9]})
				}
			}
			return bigArray;
		}
	}
}